package edu.ucsc.gameAI.hfsm;

import java.util.ArrayList;
import java.util.Collection;

import pacman.game.Game;
import pacman.game.Constants.MOVE;
import edu.ucsc.gameAI.IAction;

public class HFSM extends HState implements IHFSM {

	//List of states at this level of the hierarchy.
	//???The code in the book has all sorts of 
	Collection<IHState> states;
	
	//???We added this. Not in the book.
	IResult result;
	
	//the initial state for when the machine has no current state
	IHState initialState;
	
	//The current state of the machine.
	IHState currentState;

	public HFSM() {
		super();
		states = new ArrayList<IHState>();
	}

	public HFSM(String string) {
		super(string);
		states = new ArrayList<IHState>();
	}

	@Override
	public IResult update(Game game) {

		result = new Result();
		//System.out.println("Pacman last move: " + game.getPacmanLastMoveMade());

		if (currentState == null) {
			currentState = initialState;
			result.addAction(currentState.getEntryAction());
			return result;
		}

		IHTransition triggeredTransition = null;
		if(game.getPacmanLastMoveMade() == MOVE.RIGHT){
			System.out.println("we should be transitioning now...");
		}
		for (IHTransition transition : currentState.getTransitions()) {
			if (transition.isTriggered(game)) {
				triggeredTransition = transition;
				break;
			}
		}

		if (triggeredTransition != null) {
			result.getActions().clear();
			result.setTransition(triggeredTransition);
			result.setLevel(triggeredTransition.getLevel());
		} else {
			result = currentState.update(game);
		}

		if (result.getTransition() != null) {
			if (result.getLevel() == 0) {
				IHState targetState = result.getTransition().getTargetState();
				result.addAction(currentState.getExitAction());
				result.addAction(result.getTransition().getAction());
				result.addAction(targetState.getEntryAction());

				System.out.println("Pacman last move: " + game.getPacmanLastMoveMade());
				System.out.println("Transitioning FROM state: " + currentState.getName() + " TO state: " + targetState.getName());
				System.out.println("Current list of states:");
				for(IHState tempState : states){
					System.out.println("----->" + tempState.getName());
				}
				
				currentState = targetState;

				result.addAction(getAction());
				result.setTransition(null);
			} else if (result.getLevel() > 0) {
				result.addAction(currentState.getExitAction());
				System.out.println("Adding the current state's exit action");
				currentState = null;
				result.setLevel(result.getLevel() - 1);
			} else {
				System.out.println("Inside of this crazy thing now");

				IHState targetState = result.getTransition().getTargetState();
				IHFSM targetMachine = targetState.getParent();
				result.addAction(result.getTransition().getAction());
				result.addActions(targetMachine.updateDown(targetState,
						-result.getLevel(), game));

				result.setTransition(null);
			}
		} else {
			result.addAction(getAction());
		}

		return result;
	}

	@Override
	public void setInitialState(IHState initialState) {
		this.initialState = initialState;
	}

	@Override
	public IHState getInitialState() {
		return initialState;
	}

	public Collection<IAction> updateDown(IHState state, int level, Game game) {

		Collection<IAction> actions;

		if (level > 0)
			actions = parent.updateDown(this, level - 1, game);
		else
			actions = new ArrayList<IAction>();

		if (currentState != null)
			actions.add(exitAction);

		currentState = state;
		actions.add(state.getEntryAction());

		return actions;
	}

	@Override
	public void setStates(Collection<IHState> states) {
		this.states.addAll(states);
	}

	@Override
	public Collection<IHState> getStates() {

		if (currentState != null)
			return currentState.getStates();
		else {
			states = new ArrayList<IHState>();
			return states;
		}

	}
	
	@Override
	public IAction getAction()
	{
		if (currentState == null)
			currentState = initialState;
		return super.getAction();
	}
}
